package com.adxon.data;

import com.adxon.MsgException;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.CompositeFilterOperator;
import com.google.appengine.api.datastore.Query.Filter;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.appengine.api.datastore.Query.FilterPredicate;
import com.google.appengine.api.datastore.Query.SortDirection;

import java.util.Iterator;
public class ItemSet0 implements Iterable<Item>,Iterator<Item>{
	@SuppressWarnings("rawtypes")
	private Class			cls;
	private Iterator<Entity>itr;
	int						kdn=0;
	private Tagged0			nxt;
	int						rat=0;
	Item					tmp;

	public ItemSet0(Item template){
		//System.out.println("ItemSet3");
		String b;
		Filter f=new FilterPredicate("ta",FilterOperator.NOT_EQUAL,0);
		if(template.tg==null){
			b=Item.BSK;
			cls=Untagged0.class;
			if(template.kn>0)
				f=CompositeFilterOperator.and(f,
						new FilterPredicate("kn",FilterOperator.EQUAL,template.kn));
			else kdn=-template.kn;
			if(template.rf!=0)
				f=CompositeFilterOperator.and(f,
						new FilterPredicate("rf",FilterOperator.EQUAL,template.rf));
		}else{
			b=Tag.BSK;
			cls=Tagged0.class;
			f=CompositeFilterOperator.and(f,
					new FilterPredicate("tx",FilterOperator.EQUAL,template.tg));
		}
		if(template.ow!=0)
			f=CompositeFilterOperator.and(f,
					new FilterPredicate("ow",FilterOperator.EQUAL,template.ow));
		if(template.rt!=0)
			rat=template.rt;
		Query q=new Query(b);
		q.setFilter(f);
		q.addSort("ta",SortDirection.DESCENDING);
		itr=DatastoreServiceFactory.getDatastoreService().prepare(q).
				asIterable().iterator();
		tmp=template;
	}
	public Item getTemp(){
		return tmp;
	}
	@Override
	public boolean hasNext(){
		//System.out.println("ItemSet3: hasNext");
		if(nxt==null){
			try{
				while(itr.hasNext()){
					nxt=(Tagged0)((Tagged0)cls.newInstance()).update(itr.next());
					if(nxt.skipNext(this))
						continue;
					return true;
				}
			}catch(MsgException e){
			}catch(InstantiationException e){
			}catch(IllegalAccessException e){}
		}else return true;
		nxt=null;
		return false;
	}
	@Override
	public Iterator<Item> iterator(){
		return this;
	}
	@Override
	public Item next(){
		//System.out.println("ItemSet3: next");
		Item r=nxt.extend();
		if(tmp.sto!=0)
			r.setStarer(tmp.sto);
		nxt=null;
		return r;
	}
	@Override
	public void remove(){
	}
}
class Tagged0 extends Message{
	Item itm;

	Item extend(){
		try{
			if(itm==null)
				itm=(Item)new Item().update(id);
			Item r=itm;
			itm=null;
			return r.extend();
		}catch(MsgException e){
			e.printStackTrace();
			return null;
		}
	}
	boolean skipNext(ItemSet0 set){
		if(set.kdn!=0 && set.kdn==kn)
			return true;
		if(set.rat!=0)
			if(set.rat<100){
				if(set.rat<rt || rt>99)
					return true;
			}else if(rt<set.rat)
				return true;
		return false;
	}
}
class Untagged0 extends Tagged0{
	@Override
	Item extend(){
		try{
			@SuppressWarnings("rawtypes")
			Class c=kn<Item.CLS.length?Item.CLS[kn]:null;
			if(c==null)
				c=Item.class;
			return (Item)((Item)c.newInstance()).update(ent);
		}catch(MsgException e){
			return null;
		}catch(IllegalAccessException e){
			return null;
		}catch(InstantiationException e){
			return null;
		}
	}
	@Override
	public Untagged0 update()throws MsgException{
		super.update();
		kn=updateInt("kn");
		return this;
	}
}